package com.zzh.camera2.manager;

import android.content.Context;
import android.hardware.usb.UsbDevice;
import android.util.Log;
import android.view.TextureView;

import com.lgh.uvccamera.UVCCameraProxy;
import com.lgh.uvccamera.callback.ConnectCallback;
import com.serenegiant.usb.Size;
import com.serenegiant.usb.UVCCamera;

import java.util.List;

/**
 * @author ：zuhui.zhang
 * time ： 2021/7/30 10:46
 */
public class UvcCameraManager implements IUvcCameraManager {
    private final String TAG = UvcCameraManager.class.getSimpleName();
    private UVCCameraProxy mUVCCamera;
    //    static String dirName = "af5";
    boolean bWantHigherDepthRate = false;
    static final int RGB_WIDTH = 1280;
    static final int RGB_HEIGHT = 720;
    static int rgbRotation = 270;
    // 是否画rgb预览画面在textview上，通过调用uvc接口，从底层关闭预览画面
    boolean isDrawRgbPreview = true;
    byte[] mRgbData;
//    final int callbackPixelFormat = UVCCamera.PIXEL_FORMAT_YUV420SP;

    UvcCameraManagerHost host;

    public void setHost(UvcCameraManagerHost host) {
        this.host = host;
    }

    @Override
    public void initUVCCamera(TextureView textureView, Context context) {
        if (context == null || textureView == null) {
            return;
        }

        mUVCCamera = new UVCCameraProxy(context);
        // 已有默认配置，不需要可以不设置
//        mUVCCamera.getConfig()
//                .isDebug(true)
//                .setPicturePath(PicturePath.SDCARD)
//                .setDirName(dirName)
//                .setProductId(/*25735*/0)
//                .setVendorId(/*7749*/0);
        mUVCCamera.setPreviewTexture(textureView);

        // add by zzh for set preview callback pixel format
        //mUVCCamera.setPreviewCallbackPixelFormat(callbackPixelFormat);

        mUVCCamera.setConnectCallback(new ConnectCallback() {
            @Override
            public void onAttached(UsbDevice usbDevice) {
                Log.i(TAG, "ConnectCallback onAttached usbDevice=" + usbDevice);
                mUVCCamera.requestPermission(usbDevice);
            }

            @Override
            public void onGranted(UsbDevice usbDevice, boolean granted) {
                Log.i(TAG, "ConnectCallback onGranted=" + granted);
                if (granted && mUVCCamera != null) {
                    mUVCCamera.connectDevice(usbDevice);
                }
            }

            @Override
            public void onConnected(UsbDevice usbDevice) {
                Log.i(TAG, "ConnectCallback onConnected");
                mUVCCamera.openCamera();
            }

            @Override
            public void onCameraOpened() {
                Log.i(TAG, "ConnectCallback onCameraOpened start");
                //FRAME_FORMAT_MJPEG: rgb frame rate 30, but depth frame rate drops slightly
                //FRAME_FORMAT_YUYV: rgb frame rate drops, depth frame rate increases slightly
                if (bWantHigherDepthRate) {
                    mUVCCamera.setPreviewSize(RGB_WIDTH, RGB_HEIGHT, 30, UVCCamera.FRAME_FORMAT_MJPEG);
                } else {
                    mUVCCamera.setPreviewSize(RGB_WIDTH, RGB_HEIGHT, UVCCamera.FRAME_FORMAT_YUYV);
                }
                switchUVCPreview(true);
                Log.i(TAG, "zzh uvc start preview 1");
                mUVCCamera.setPreviewRotation(rgbRotation);
                // add by zzh, must called after startPreview() @{
                //mUVCCamera.setIsDrawPreview(isDrawRgbPreview);
                // @}

                // add by zzh
                List<Size> supportPreviewSize = mUVCCamera.getSupportedPreviewSizes();
                if (supportPreviewSize != null && supportPreviewSize.size() > 0) {
                    for (int i = 0; i < supportPreviewSize.size(); i++) {
                        Log.i(TAG, "uvc supportPreviewSize[" + i + "]=" + supportPreviewSize.get(i));
                    }
                }
                Log.i(TAG, "ConnectCallback onCameraOpened end");
            }

            @Override
            public void onDetached(UsbDevice usbDevice) {
                mUVCCamera.closeCamera();
                Log.i(TAG, "ConnectCallback onDetached usbDevice=" + usbDevice);
            }
        });

        mUVCCamera.setPreviewCallback(yuv -> {
            //record rgb data
            mRgbData = yuv;
            //Log.d(TAG, "yuv length=" + yuv.length);
            if (host != null) {
                host.onUvcPreviewCallback(yuv);
            }
        });

        // 必须放在setConnectCallback之后调用
//        mUVCCamera.checkDevice();
    }

    @Override
    public void switchUVCPreview(boolean showPreview) {
        if (mUVCCamera != null) {
            if (showPreview) {
                // 开始RGB摄像头预览
                mUVCCamera.startPreview();
            } else {
                mUVCCamera.stopPreview();
                mUVCCamera.clearCache();
            }
        }
    }

    @Override
    public void switchIsDrawRgbPreview() {
        isDrawRgbPreview = !isDrawRgbPreview;
        if (mUVCCamera != null) {
            mUVCCamera.setIsDrawPreview(isDrawRgbPreview);
        }
    }

    @Override
    public boolean isDrawRgbPreview() {
        return isDrawRgbPreview;
    }

    @Override
    public void closeUVCCamera() {
        if (mUVCCamera != null) {
            mUVCCamera.closeCamera();
//            mUVCCamera.closeDevice();
            mUVCCamera = null;
        }
    }
}
